package com.ai.module.user.service.impl;

import com.ai.common.BaseResp;
import com.ai.module.business.domain.entity.BannerRecordEntity;
import com.ai.module.business.domain.entity.UserImageMangeEntity;
import com.ai.module.business.enu.Source;
import com.ai.module.business.service.BannerRecordService;
import com.ai.module.business.service.UserImageMangeService;
import com.ai.module.chat.common.base.ThreadLocalContext;
import com.ai.module.chat.common.constant.FileStringConstant;
import com.ai.module.chat.common.domain.bo.AliUploadBo;
import com.ai.module.chat.common.domain.vo.RiskReason;
import com.ai.module.chat.common.domain.vo.chat.ChatContent;
import com.ai.module.chat.common.enu.AliFileSource;
import com.ai.module.chat.common.enu.AliyunImageCheck;
import com.ai.module.chat.config.advice.exception.BusinessException;
import com.ai.module.chat.config.properties.AliyunProperty;
import com.ai.module.chat.util.DateUtils;
import com.ai.module.chat.util.aliyun.AliyunUtil;
import com.ai.module.mj.constant.stringConstant.ReturnCode;
import com.ai.module.user.domain.entity.*;
import com.ai.module.user.domain.req.UserRobotReq;
import com.ai.module.user.domain.vo.UserLoginInfo;
import com.ai.module.user.domain.vo.UserRobotVo;
import com.ai.module.user.mapper.ChatContentMapper;
import com.ai.module.user.mapper.UserImageMapper;
import com.ai.module.user.mapper.UserRobotMapper;
import com.ai.module.user.service.*;
import com.aliyun.green20220302.models.ImageModerationResponseBody;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.ai.module.chat.common.enu.AliFileSource.ROBOT_AVATAR;

/**
 * @author: MrHe
 * @create: 2023-11-25 11:38
 * @description: 用于用户 session维护
 **/
@Service
@Slf4j
public class UserRobotServiceImpl extends ServiceImpl<UserRobotMapper, UserRobotEntity> implements UserRobotService {

    @Autowired
    private ChatContentService chatContentService;

    @Autowired
    private ChatContentMapper chatContentMapper;

    @Autowired
    private UserRobotMapper userRobotMapper;

    @Autowired
    private UserImageMapper userImageMapper;

    @Autowired
    @Lazy
    private UserTaskService userTaskService;

    @Autowired
    @Lazy
    private UserMangeService userMangeService;

    @Autowired
    AliyunProperty aliyunProperty;
    @Autowired
    private BannerRecordService bannerRecordService;

    @Autowired
    private UserImageMangeService userImageMangeService;

    @Override
    public boolean save(UserRobotEntity entity) {
        UserRobotEntity one = getOne(
                new LambdaQueryWrapper<UserRobotEntity>()
                        .eq(UserRobotEntity::getUuid, entity.getUuid())
        );
        if (one == null) {
            return super.save(entity);
        }
        return false;

    }

    @Override
    public List<UserRobotEntity> history(String userId) {
        List<UserRobotEntity> list = list(new LambdaQueryWrapper<UserRobotEntity>()
                .eq(UserRobotEntity::getUserId, userId)
                .orderByDesc(UserRobotEntity::getId)
                .last(" limit 10"));
        return list;
    }

    @Override
    public boolean updateRobot(UserRobotReq robotReq) {
        UserRobotEntity userRobot = new UserRobotEntity();
        String robotName = robotReq.getRobotName();
        if (StringUtils.hasText(robotName)) {
            userRobot.setRobotName(robotName);
        }
        String imageUrl = robotReq.getImageUrl();
        if (StringUtils.hasText(imageUrl)) {
            userRobot.setImageUrl(imageUrl);
        }
        String backGroundUrl = robotReq.getBackGroundUrl();
        if (StringUtils.hasText(backGroundUrl)) {
            userRobot.setBackGroundUrl(backGroundUrl);
        }
        userRobot.setUuid(robotReq.getRobotId());
        dealRobotCheck(robotReq, userRobot);
        return update(userRobot, new LambdaQueryWrapper<UserRobotEntity>()
                .eq(UserRobotEntity::getUuid, robotReq.getRobotId()));
    }

    @Override
    public IPage<ChatContent> chatInfoList(UserRobotReq req) {
        String robotId = req.getRobotId();
        int currentPage = req.getPage();
        Page<ChatContentEntity> objectPage = new Page<>(currentPage, req.getSize());
        Page<ChatContent> page = chatContentMapper.selectCurrentChatList(objectPage,
                robotId,
                ThreadLocalContext.getUserId()
        );
        List<ChatContent> chatContentEntities = page.getRecords();
        List<ChatContent> chatContents = new ArrayList<>();
        chatContentEntities.forEach(chatSession -> {
           // String userContent = chatSession.getContent();
           // String uuid = chatSession.getUuid();
           // String chatGpt = chatSession.getChatGpt();
           // ChatContent userChat = new ChatContent();
           // userChat.setContent(userContent);
           // userChat.setUuid(USER_TYPE + uuid);
           // userChat.setType(USER_TYPE);
           // userChat.setUpdatedTime(chatSession.getUpdatedTime());
           // userChat.setAiContent(chatGpt);
           // chatContents.add(userChat);
            String chatGpt = chatSession.getChatGpt();
            if (StringUtils.hasText(chatGpt)){
                String modifiedText =
                        chatGpt
                                .replaceAll("(?i)chatgpt", "***")
                                .replaceAll("(?i)openai", "***").
                                replaceAll("(?i)gpt", "***");
                chatSession.setChatGpt(modifiedText);
            }
            String content = chatSession.getContent();
            if (StringUtils.hasText(content)){
                String modifiedText =
                        content.replaceAll("(?i)chatgpt", "***")
                                .replaceAll("(?i)openai", "***").
                                replaceAll("(?i)gpt", "***");
                chatSession.setContent(modifiedText);
            }

        });
//        if (currentPage == 1){
//            Collections.reverse(chatContentEntities);
//         }
//        page.setRecords(chatContents);
        return page;
    }


    @Override
    public String create(UserRobotReq robotReq) {
        UserRobotEntity userRobot = new UserRobotEntity();
        userRobot.setUserId(ThreadLocalContext.getUserId());
        String message = robotReq.getRobotName();
        if (message.length() > 15) {
            message = message.substring(0, 15);
            userRobot.setRobotName(message);
        } else {
            userRobot.setRobotName(message);
        }
        Integer robotType = robotReq.getRobotType();
        if (robotType != null) {
            userRobot.setRobotType(robotType);
        }
        String uuid = UUID.randomUUID().toString();
        userRobot.setUuid(uuid);
        dealRobotCheck(robotReq, userRobot);
        this.save(userRobot);
        return message;
    }

    private void dealRobotCheck(UserRobotReq robotReq, UserRobotEntity userRobot) {
        String realRobotName = userRobot.getRobotName();
        RiskReason riskReason = AliyunUtil.getRiskReason(realRobotName);
        Boolean success = riskReason.getSuccess();
        if (!success) {
            bannerRecordService.textCheck(String.join(",", riskReason.getRiskWords()),
                    robotReq.getRobotId(),
                    realRobotName,
                    Source.ROBOT_NAME
            );
            throw new BusinessException("AI名称违反相关规则", ReturnCode.FAILURE);
        }
        // 校验 背景图和头像
        String imageUrl = robotReq.getImageUrl();
        if (StringUtils.hasText(imageUrl)){
            // checkImageUrl(robotReq, imageUrl);
        }
        String backGroundUrl = robotReq.getBackGroundUrl();
        if (StringUtils.hasText(backGroundUrl)){
            // checkImageUrl(robotReq, backGroundUrl);
        }
    }

    private void checkImageUrl(UserRobotReq robotReq, String imageUrl) {
        try {
            ImageModerationResponseBody.ImageModerationResponseBodyDataResult result = AliyunUtil.doRealCheckImage(imageUrl);
            String bannerLabel = result.getLabel();
            // 图片审核
            if (StringUtils.hasText(bannerLabel)){
                BannerRecordEntity bannerRecord = new BannerRecordEntity();
                String desc = AliyunImageCheck.getDescByName(bannerLabel);
                bannerRecord.setRule(desc);
                bannerRecord.setBusinessId(robotReq.getRobotId());
                bannerRecord.setOriginalRule(bannerLabel);
                bannerRecord.setBusinessContent(imageUrl);
                bannerRecord.setUserId(ThreadLocalContext.getUserId());
                bannerRecord.setSource(Source.ROBOT_NAME);
                bannerRecordService.save(bannerRecord);
                throw new BusinessException(desc.split("。")[0], ReturnCode.FAILURE);
            }
        } catch (Exception e) {
            if (e instanceof BusinessException){
                throw (BusinessException)e;
            }
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<UserRobotVo> findALL() {
        return baseMapper.findByRobotList(ThreadLocalContext.getUserId());
    }

    @Override
    public BaseResp<String> uploadImage(MultipartFile file, String robotId, AliFileSource imageSource) {
        try {
            String bucketName = aliyunProperty.getOssBucketName();
            UserLoginInfo userLoginInfo = ThreadLocalContext.getUserLoginInfo();
            String projectName = userLoginInfo.getTaskImageUrl(FileStringConstant.USER_SETTING,FileStringConstant.ROBOT_IMAGE, robotId);
            File backGroundImage = multipartFileToFile(file, projectName);
           // Date expireTime = new Date(System.currentTimeMillis() + DateUtils.MONTH_DAY);
            AliUploadBo aliUploadBo = new AliUploadBo();

            aliUploadBo.setExpireDate(LocalDateTime.now().plusMonths(6));
            aliUploadBo.setProjectName(projectName);

            String imageUrl = AliyunUtil.uploadOSSFile(backGroundImage, aliUploadBo);
            ImageModerationResponseBody.ImageModerationResponseBodyDataResult result = AliyunUtil.doRealCheckImage(imageUrl);
            String bannerLabel = result.getLabel();
            // 图片审核
            if (StringUtils.hasText(bannerLabel)){
                BannerRecordEntity bannerRecord = new BannerRecordEntity();
                String desc = AliyunImageCheck.getDescByName(bannerLabel);
                bannerRecord.setRule(desc);
                bannerRecord.setBusinessId(null);
                bannerRecord.setOriginalRule(bannerLabel);
                bannerRecord.setBusinessContent(imageUrl);
                bannerRecord.setUserId(ThreadLocalContext.getUserId());
                bannerRecord.setSource(Source.IMAGE_UPLOAD);
                bannerRecord.setConfidence(result.getConfidence());
                bannerRecordService.save(bannerRecord);
                throw new BusinessException(desc.split("。")[0], ReturnCode.FAILURE);
            }
            // 更新上传记录
            UserImageEntity userImage = new UserImageEntity();
            userImage.setExpireTime(LocalDateTime.now().plus(DateUtils.HALF_YEAR, ChronoUnit.MILLIS));
            userImage.setBucketName(bucketName);
            userImage.setUserId(ThreadLocalContext.getUserId());
            userImage.setImageSource(imageSource);
            userImage.setFilePath(imageUrl);

            switch (imageSource) {
                case ROBOT_AVATAR:
                case ROBOT_BACKGROUND:
                    UserRobotReq userRobot = new UserRobotReq();
                    if (imageSource == ROBOT_AVATAR) {
                        userRobot.setImageUrl(imageUrl);
                    } else {
                        userRobot.setBackGroundUrl(imageUrl);
                    }
                    userRobot.setRobotId(robotId);
                    log.info("用户进行AI设置[{}]", userRobot);
                    // updateRobot(userRobot);
                    userImage.setBusinessId(robotId);
                    break;
                case USER_AVATAR:
                    userImage.setBusinessId(ThreadLocalContext.getUserId());
                    UserMangeEntity userMange = new UserMangeEntity();
                    LambdaQueryWrapper<UserMangeEntity> updateQuery = new LambdaQueryWrapper<UserMangeEntity>()
                            .eq(UserMangeEntity::getUuid, ThreadLocalContext.getUserId());
                    userMange.setIcon(imageUrl);
                    log.info("用户进行数据设置[{}]", userMange);
                    userMangeService.update(userMange, updateQuery);
            }

            userImage.setFileName(backGroundImage.getName());
            userImage.setProjectName(projectName);
            userImageMapper.insert(userImage);

            UserImageMangeEntity userImageMange = new UserImageMangeEntity();
            BeanUtils.copyProperties(userImage,userImageMange);
            userImageMangeService.save(userImageMange);

            return BaseResp.success(imageUrl);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException(e.getMessage(),ReturnCode.FAILURE);

        }

    }

    /**
     * 将MultipartFile转换为File
     *
     * @param multiFile
     * @param projectName
     * @return
     */
    public File multipartFileToFile(MultipartFile multiFile, String projectName) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀(.xml)
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        // 若要防止生成的临时文件重复,需要在文件名后添加随机码
        try {
            //"tmp", ".txt"
            //fileName这块可以根据自己的业务需求进行修改，我这里没有做任何处理
            File file = File.createTempFile(projectName, suffix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public UserRobotVo findByRobotId(String robotId) {
        List<UserRobotVo> currentRobotList = this.userRobotMapper.findByRobotId(robotId, ThreadLocalContext.getUserId());
        if (CollectionUtils.isEmpty(currentRobotList)) {
            throw new BusinessException("AI已删");
        }
        return currentRobotList.get(0);
    }

    @Override
    @Transactional
    public void deleteRobot(UserRobotReq req) {
        String userId = ThreadLocalContext.getUserId();
        Integer robotType = req.getRobotType();
        String robotId = req.getRobotId();
        boolean remove = this.remove(new LambdaQueryWrapper<UserRobotEntity>()
                .eq(UserRobotEntity::getUserId, userId)
                .eq(UserRobotEntity::getUuid, robotId)
                .notIn(UserRobotEntity::getIsDefault, 1)
        );
        if (! remove){
            throw new BusinessException("删除失败");
        }
        if (robotType == 1) {
            chatContentMapper.delete(new LambdaQueryWrapper<ChatContentEntity>()
                    .eq(ChatContentEntity::getUserId, userId)
                    .eq(ChatContentEntity::getRobotId, robotId)
            );
        }
        if (robotType == 2) {
            userTaskService.remove(new LambdaQueryWrapper<UserTaskEntity>()
                    .eq(UserTaskEntity::getUserId, userId)
                    .eq(UserTaskEntity::getUuid, robotId)
            );
            // 删除提示词

            // 删除背景图 todo 删除阿里云数据
            // 图片删除
        }

    }

    @Autowired
    private UserPromptService userPromptService;

    @Override
    public UserRobotVo findDefaultRobot(UserRobotReq userRobotReq) {
        Integer robotType = userRobotReq.getRobotType();
        if (robotType ==null){
            throw new BusinessException("缺少robotType");
        }
        LambdaQueryWrapper<UserRobotEntity> userQuery = new LambdaQueryWrapper<UserRobotEntity>()
                .eq(UserRobotEntity::getRobotType, robotType)
                .eq(UserRobotEntity::getIsDefault, 1)
                .eq(UserRobotEntity::getUserId, ThreadLocalContext.getUserId());
        UserRobotEntity userRobot = this.getOne(userQuery);
        if (userRobot== null){
            throw new BusinessException("默认AI不存在 !!!");
        }
        UserRobotVo robotVo = new UserRobotVo();
        BeanUtils.copyProperties(userRobot,robotVo);
        return robotVo;
    }

    @Override
    public List<UserRobotEntity> findSessions() {
        String userId = ThreadLocalContext.getUserId();
        if (StringUtils.isEmpty(userId)){
            return new ArrayList<>();
        }
        LambdaQueryWrapper<UserRobotEntity> query = new LambdaQueryWrapper<UserRobotEntity>()
                .eq(UserRobotEntity::getUserId, userId)
                .eq(UserRobotEntity::getRobotType, 1)
                .orderByDesc(UserRobotEntity::getUpdatedTime)
                ;
        return this.list(query);
    }
}
